/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hyce;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;

/**
 *
 * @author goodsam
 */
public class Encryptor
{
    final private int ENCRYPTCHUNKSIZE = 256;
    private SecretKey passwordKey;
    private PBEParameterSpec parameterSpec;
    private Cipher cipher;
    public byte[] salt;

    public void initializeEncryption(String password) throws Exception
    {
        this.createSecretKey(password);
        this.createParameterSpec();
        this.createCipher();
    }

    public void createSecretKey(String password) throws Exception
    {
        PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
        SecretKeyFactory keyFactory =
            SecretKeyFactory.getInstance("PBEWithMD5AndDES");
        this.passwordKey = keyFactory.generateSecret(keySpec);
    }

    public void createParameterSpec()
    {
        this.salt = new byte[8];
        Random rnd = new Random();
        rnd.nextBytes(salt);
        int iterations = 100;

        //Create the parameter spec for this salt and interation count

        this.parameterSpec = new PBEParameterSpec(salt, iterations);
    }

    public void createCipher() throws Exception
    {
        this.cipher = Cipher.getInstance("PBEWithMD5AndDES");
        this.cipher.init(Cipher.ENCRYPT_MODE, passwordKey, parameterSpec);
    }

    public byte[] toByteArray (Object obj)
    {
        byte[] bytes = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try
        {
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(obj);
            oos.flush();
            oos.close();
            bos.close();
            bytes = bos.toByteArray ();
        }
        catch (IOException ex)
        {
        //TODO: Handle the exception
        }
        return bytes;
}


    public void encrypt(Object toEncrypt, FileOutputStream out) throws Exception
    {
       if (this.passwordKey != null && this.parameterSpec != null
               && this.cipher != null && this.salt != null)
       {

           DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
           Date date = new Date();

           out.write(salt);
           System.out.println("Encryption started.  Time: " + dateFormat.format(date));
           //byte[] input = new byte[64];
           byte[] object = toByteArray(toEncrypt);

           //ByteArrayOutputStream bos = new ByteArrayOutputStream();
           //ObjectOutputStream oos = new ObjectOutputStream(bos);
           //oos.writeObject(toEncrypt);

           byte[] output = cipher.update(object);
           if (output!= null) out.write(output);
           out.flush();
           out.close();

           dateFormat = new SimpleDateFormat("HH:mm:ss");
           date = new Date();
           System.out.println("Encryption ended.   Time: " + dateFormat.format(date));

       }
    }
}
